﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace FMSpaceShooter.Screens
{
    class Resolution
    {
        private int width;
        private int height;

        public int Height
        {
            get { return height; }
            set { height = value; }
        }

        public int Width
        {
            get { return width; }
            set { width = value; }
        }
    }

    class OptionsMenuScreen : MenuScreen
    {
        GraphicsDeviceManager graphics;
        const int timeToSave = 15;
        bool isFullscreen = Data.ConfigFile.Instance.Options.IsFullscreen;
        List<Resolution> displayOptions = new List<Resolution>();
        Resolution selectedDisplayMode;

        DateTime? startSave = null;
        Resolution oldDisplay;
        bool oldFull;

        MenuEntry fullscreenOption = new MenuEntry(string.Empty);
        MenuEntry resolutionOption = new MenuEntry(string.Empty);
        MenuEntry applyOption = new MenuEntry(string.Empty);
        MenuEntry cancelOption = new MenuEntry("Back");



        public OptionsMenuScreen()
            : base("Options Menu")
        {
            // Hook up menu event handlers.
            fullscreenOption.Selected += FullscreenOptionSelected;
            resolutionOption.Selected += ResolutionOptionSelected;
            applyOption.Selected += ApplyOptionSelected;

            cancelOption.Selected += OnCancel;

            // Add entries to the menu.
            MenuEntries.Add(fullscreenOption);
            MenuEntries.Add(resolutionOption);
            MenuEntries.Add(applyOption);
            MenuEntries.Add(cancelOption);
        }

        public override void LoadContent()
        {
            base.LoadContent();

            graphics = ((Game1)ScreenManager.Game).GDM;

            foreach (DisplayMode mode in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
            {
                Resolution res = new Resolution { Height = mode.Height, Width = mode.Width };
                displayOptions.Add(res);
                if (mode.Height == graphics.PreferredBackBufferHeight &&
                    mode.Width == graphics.PreferredBackBufferWidth)
                {
                    selectedDisplayMode = res;
                }
            }

            if (selectedDisplayMode == null)
            {
                Resolution res = new Resolution
                                        {
                                            Height = graphics.PreferredBackBufferHeight,
                                            Width = graphics.PreferredBackBufferWidth
                                        };
                displayOptions.Add(res);
                selectedDisplayMode = res;
            }

            SetMenuEntryText();
            setApplyText();
        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);

            if (startSave != null)
            {
                DateTime start = (DateTime)startSave;

                int elapsed = (int)((DateTime.Now - start).TotalSeconds);
                if (elapsed <= timeToSave)
                {
                    setApplyText(timeToSave - elapsed);
                }
                else
                {
                    changeDisplayMode(oldDisplay, oldFull);
                    setApplyText();
                }
            }
        }

        void ApplyOptionSelected(object sender, EventArgs e)
        {
            if (startSave == null)
            {

                oldDisplay = new Resolution
                {
                    Height = graphics.PreferredBackBufferHeight,
                    Width = graphics.PreferredBackBufferWidth
                };

                oldFull = graphics.IsFullScreen;

                changeDisplayMode(selectedDisplayMode, isFullscreen);
                startSave = DateTime.Now;
            }
            else
            {
                startSave = null;
                saveGraphicsSettings();
                setApplyText();
            }
        }

        void saveGraphicsSettings()
        {
            Data.ConfigFile.Instance.Options.ResolutionX = graphics.PreferredBackBufferWidth;
            Data.ConfigFile.Instance.Options.ResolutionY = graphics.PreferredBackBufferHeight;
            Data.ConfigFile.Instance.Options.IsFullscreen = graphics.IsFullScreen;
            Data.ConfigFile.Instance.SaveConfig();
        }

        void setApplyText(int seconds = -1)
        {
            if (seconds == -1)
            {
                applyOption.Text = "Apply Settings";
            }
            else
            {
                // will probably change this
                applyOption.Text = string.Format("Save Settings ({0})", seconds);
            }
        }

        void changeDisplayMode(Resolution dest, bool isFull)
        {
            GraphicsDeviceManager graphics = ((Game1)ScreenManager.Game).GDM;
            graphics.PreferredBackBufferHeight = dest.Height;
            graphics.PreferredBackBufferWidth = dest.Width;
            graphics.IsFullScreen = isFull;
            graphics.ApplyChanges();
        }

        void FullscreenOptionSelected(object sender, EventArgs e)
        {
            if (startSave == null)
            {
                isFullscreen = !isFullscreen;
                SetMenuEntryText();
            }
        }

        void ResolutionOptionSelected(object sender, EventArgs e)
        {
            if (startSave == null)
            {
                selectedDisplayMode = displayOptions[(displayOptions.IndexOf(selectedDisplayMode) + 1)
                                                        % displayOptions.Count];
                SetMenuEntryText();
            }
        }

        void SetMenuEntryText()
        {
            fullscreenOption.Text = "Window Type: " + (isFullscreen ? "Fullscreen" : "Windowed");
            if (selectedDisplayMode != null)
            {
                resolutionOption.Text = string.Format("Resolution: {0}x{1}",
                    selectedDisplayMode.Width,
                    selectedDisplayMode.Height);
            }
        }
    }
}
